package model

import (
	"encoding/json"
	"log"
	"unsafe"

	"github.com/tidwall/gjson"
	"gopkg.in/mgo.v2/bson"
	"hass.tree.com/bridge/dbhelper"
)

func MongoAdd(collectionName string, jsonStr string) {
	var obj interface{}
	json.Unmarshal([]byte(jsonStr), &obj)
	collection := dbhelper.MongoDB.C(collectionName)

	err := collection.Insert(&obj)
	if err != nil {
		log.Fatal(err)
	}
}

func jsonStr2Bson(str string) (interface{}, error) {
	var want interface{}
	err := bson.UnmarshalJSON([]byte(str), &want)
	if err != nil {
		return nil, err
	}
	return want, nil
}

func MongoList(collectionName string, conditionJSON string, sort []string, pageQuery string) []interface{} {
	id := gjson.Get(conditionJSON, "_id")
	var results []interface{}
	collection := dbhelper.MongoDB.C(collectionName)
	if len(id.Str) > 0 {
		objectId := bson.ObjectIdHex(id.Str)
		collection.Find(bson.M{"_id": objectId}).All(&results)
		return results
	} else {
		condition, _ := jsonStr2Bson(conditionJSON)
		query := collection.Find(condition).Sort(sort...)
		if len(pageQuery) > 0 {
			size := gjson.Get(pageQuery, "size").Int()
			page := gjson.Get(pageQuery, "page").Int()
			if page < 1 {
				page = 1
			}
			int_size := *(*int)(unsafe.Pointer(&size))
			int_page := *(*int)(unsafe.Pointer(&page))
			query = query.Skip((int_page - 1) * int_size).Limit(int_size)
		}
		query.All(&results)
		return results
	}
}

func MongoDelete(collectionName string, id string) {
	collection := dbhelper.MongoDB.C(collectionName)
	objectId := bson.ObjectIdHex(id)
	err := collection.Remove(bson.M{"_id": objectId})
	if err != nil {
		log.Fatal(err)
	}
}

func MongoUpdate(collectionName string, id string, dataJSON string) {
	collection := dbhelper.MongoDB.C(collectionName)
	objectId := bson.ObjectIdHex(id)
	data, _ := jsonStr2Bson(dataJSON)
	err := collection.Update(bson.M{"_id": objectId}, bson.M{"$set": data})
	if err != nil {
		log.Fatal(err)
	}
}
